//
//  TUIBaseChatViewController.m
//  UIKit
//
//  Created by annidyfeng on 2019/5/21.
//

#import "TUIBaseChatViewController.h"
#import <MobileCoreServices/MobileCoreServices.h>
#import <AVFoundation/AVFoundation.h>
#import <AssetsLibrary/AssetsLibrary.h>
#import <Photos/Photos.h>
#import "ReactiveObjC/ReactiveObjC.h"
#import "TUIBaseMessageController.h"
#import "TUIImageMessageCellData.h"
#import "TUIVideoMessageCellData.h"
#import "TUIFileMessageCellData.h"
#import "TUIVoiceMessageCellData.h"
#import "TUIDefine.h"
#import "TUIMessageMultiChooseView.h"
#import "TUIMessageController.h"
#import "TUIChatDataProvider.h"
#import "TUIMessageDataProvider.h"
#import "TUICameraViewController.h"
#import "TUITool.h"
#import "TUICore.h"
#import "TUIDefine.h"
#import "NSDictionary+TUISafe.h"
#import "NSString+emoji.h"
#import "TUIThemeManager.h"
#import "TUIBaseChatViewController+AuthControl.h"
#import "TUIMessageReadViewController.h"
#import "TUIJoinGroupMessageCell.h"
#import "TUICloudCustomDataTypeCenter.h"
#import "TUILogin.h"
#import "TUIChatConfig.h"
#import "TUIChatModifyMessageHelper.h"
#import "YBGiftVC.h"
#import "YBGIftAnimationVC.h"
#import "YBChooseWhoToGiftVC.h"
#import "YBMoveScreenView.h"
#import "YBTopUpVC.h"
#import "YBRedEnvelopeCell.h"
#import "YBGiftCell.h"
#import "YBBurnAfterReadingCell.h"
#import "TUITextMessageCell.h"
#import "YBRedEnvelopeVC.h"
#import "YBReceiveRedEnvelopeVC.h"
#import "YBRedPackListModel.h"
#import "YBFamilyModel.h"
#import "YBSendGiftAlertView.h"
#import "IQKeyboardManager.h"
#import "YBCommonWordsVC.h"
#import "YBUserInfoAlertVC.h"
#import "YBPlacetopView.h"
#import "YBChatUserInfoView.h"
#import "YBChatSetVC.h"
#import "YBFamilyDetailVC.h"
#import "YBChatCallAlertView.h"
#import "TUICallKit.h"
#import "YBIntimacyAlertView.h"
#import "YBIntimacyIconView.h"
#import "YBAppuserisBlackModel.h"
#import "YBUserInfoDetailVC.h"
#import "YBBurnAfterReadingVC.h"

static UIView *customTopView;

@interface TUIBaseChatViewController () <TUIBaseMessageControllerDelegate, TInputControllerDelegate, UIImagePickerControllerDelegate, UIDocumentPickerDelegate, UINavigationControllerDelegate, TUIMessageMultiChooseViewDelegate, TUIChatDataProviderForwardDelegate, TUINotificationProtocol, TUIJoinGroupMessageCellDelegate,YBGiftCellDelegate, V2TIMConversationListener,V2TIMGroupListener, TUINavigationControllerDelegate>
@property (nonatomic, strong) TUINaviBarIndicatorView *titleView;
@property (nonatomic, strong) TUIMessageMultiChooseView *multiChooseView;
@property (nonatomic, assign) BOOL responseKeyboard;
// @{@"serviceID" : serviceID, @"title" : @"Video call", @"image" : image}
@property (nonatomic, strong) NSMutableArray<NSDictionary *> *resgisterParam;
@property (nonatomic, strong) TUIChatDataProvider *dataProvider;

@property (nonatomic, weak) UIViewController *forwardConversationSelectVC;
@property (nonatomic) NSArray<TUIMessageCellData *> *forwardSelectUIMsgs;
@property (nonatomic) BOOL isMergeForward;

@property (nonatomic, assign) BOOL firstAppear;

@property (nonatomic, copy) NSString *mainTitle;

@property (nonatomic, strong) UIImageView *backgroudView;

// 送礼控制器
@property (nonatomic, strong) YBGiftVC *yBGiftVC;
// 群聊时家族详情
@property (nonatomic, strong) YBFamilyModel *familyModel;
// 群聊时家族入场通知
@property (nonatomic, assign) BOOL isShowNotice;
// 单聊时好友详情
@property (nonatomic, strong) YBLoginUserInfoModel *friendInfoModel;
// 亲密信息
@property (nonatomic, strong) YBAppuserisBlackModel *blackModel;
// 置顶信息
@property (nonatomic, strong) TUITextMessageCellData *lastTextCellData;
// 置顶视图
@property (nonatomic, strong) YBPlacetopView *placetopView;
// 用户信息
@property (nonatomic, strong) YBChatUserInfoView *userInfoView;
// 亲密度
@property (nonatomic, strong) YBIntimacyIconView *intimacyIconView;
// 亲密度
@property (nonatomic, assign) CGFloat intimacy;

@end

@implementation TUIBaseChatViewController

#pragma mark - Life Cycle
- (instancetype)init {
    self = [super init];
    if (self) {
        [TUIBaseChatViewController createCachePath];
    }
    return self;
}

- (void)setTitle:(NSString *)title
{
    self.mainTitle = title;
}

- (void)viewDidLoad {
    [super viewDidLoad];
    
    self.firstAppear = YES;
    self.view.backgroundColor = TUICoreDynamicColor(@"controller_bg_color", @"#FFFFFF");
    self.edgesForExtendedLayout = UIRectEdgeNone;

    [self configBackgroundView];
    
    [self configNotify];

    // setup UI
    [self setupNavigator];
    if (customTopView) {
        [self setupCustomTopView];
    }
    [self setupMessageController];
    [self setupInputController];
    
    // data provider
    self.dataProvider = [[TUIChatDataProvider alloc] init];
    self.dataProvider.forwardDelegate = self;
    
    if (self.conversationData.groupID.length > 0) {
        //代表群聊
        self.inputController.inputBar.topSwitchButton.hidden = NO;
        self.inputController.inputBar.chatMsgButton.hidden = YES;
        self.inputController.inputBar.callButton.hidden = YES;
        UIEdgeInsets edge = self.inputController.inputBar.inputTextView.textContainerInset;
        edge.left = 50.;
        edge.right = 11.;
        self.inputController.inputBar.inputTextView.textContainerInset = edge;
        
        [self requestGetFamilyDetailInfo];

    }else {
        if ([self.conversationData.userID isEqualToString:@"administrator"]) {
            //小秘书
            self.inputController.inputBar.topSwitchButton.hidden = YES;
            self.inputController.inputBar.chatMsgButton.hidden = NO;
            UIEdgeInsets edge = self.inputController.inputBar.inputTextView.textContainerInset;
            edge.left = 11.;
            edge.right = 40.;
            self.inputController.inputBar.inputTextView.textContainerInset = edge;
            self.inputController.inputBar.redEnvelopeButton.hidden = YES;
            self.inputController.inputBar.callButton.hidden = YES;
            self.inputController.inputBar.giftButton.hidden = YES;
            
        } else {
            //代表单聊
            self.inputController.inputBar.topSwitchButton.hidden = YES;
            self.inputController.inputBar.chatMsgButton.hidden = NO;
            UIEdgeInsets edge = self.inputController.inputBar.inputTextView.textContainerInset;
            edge.left = 11.;
            edge.right = 40.;
            self.inputController.inputBar.inputTextView.textContainerInset = edge;

            [self.view addSubview:self.intimacyIconView];
            [self requestUserInfo];
            [self requestAppGuardGetToUserIntimacy];
            [self requestAppuserisBlack];
        }
    }
    if (kIsShowScore) {
        self.inputController.inputBar.redEnvelopeButton.hidden = YES;
        self.inputController.inputBar.giftButton.hidden = YES;
    }
}

- (void)dealloc {
    [TUICore unRegisterEventByObject:self];
}

- (void)willMoveToParentViewController:(UIViewController *)parent
{
    if (parent == nil) {
        [self saveDraft];
    }
}

- (void)viewDidAppear:(BOOL)animated {
    [super viewDidAppear:animated];
    
    [[IQKeyboardManager sharedManager] setEnable:NO];
    [[IQKeyboardManager sharedManager] setEnableAutoToolbar:NO];

    self.responseKeyboard = YES;
    if (self.firstAppear) {
        [self loadDraft];
        self.firstAppear = NO;
    }
}

- (void)viewWillDisappear:(BOOL)animated {
    [super viewWillDisappear:animated];
    self.responseKeyboard = NO;
    [self openMultiChooseBoard:NO];
    [self.messageController enableMultiSelectedMode:NO];
}

- (void)viewDidDisappear:(BOOL)animated
{
    [super viewDidDisappear:animated];
    
    [[IQKeyboardManager sharedManager] setEnable:YES];
    [[IQKeyboardManager sharedManager] setEnableAutoToolbar:YES];

    if (self.inputController.status == Input_Status_Input ||
        self.inputController.status == Input_Status_Input_Keyboard) {
        CGPoint offset = self.messageController.tableView.contentOffset;
        __weak typeof(self) weakSelf = self;
        dispatch_async(dispatch_get_main_queue(), ^{
            __strong typeof(weakSelf)strongSelf = weakSelf;
            strongSelf.responseKeyboard = YES;
            [UIApplication.sharedApplication.keyWindow endEditing:YES];
            [strongSelf inputController:strongSelf.inputController didChangeHeight:CGRectGetMaxY(strongSelf.inputController.inputBar.frame) + Bottom_SafeHeight];
            [strongSelf.messageController.tableView setContentOffset:offset];
        });
    }
}

- (void)setupNavigator
{
//    TUINavigationController *naviController = (TUINavigationController *)self.navigationController;
//    naviController.uiNaviDelegate = self;
    _titleView = [[TUINaviBarIndicatorView alloc] init];
    self.navigationItem.titleView = _titleView;
    self.navigationItem.title = @"";
    __weak typeof (self)weakSelf = self;
    [[RACObserve(_conversationData, title) distinctUntilChanged] subscribeNext:^(NSString *title) {
        if ([weakSelf.conversationData.userID isEqualToString:@"administrator"]) {
            [weakSelf.titleView setTitle:@"伊贝小秘书"];
        }else {
            [weakSelf.titleView setTitle:title];
        }
    }];
    
    [[RACObserve(_conversationData, otherSideTyping) distinctUntilChanged] subscribeNext:^(id otherSideTyping) {
        BOOL otherSideTypingFlag =  [otherSideTyping boolValue];
        if (!otherSideTypingFlag) {
            [weakSelf checkTitle:YES];
        }
    }];
    
    [self checkTitle:NO];
    
    [TUIChatDataProvider getTotalUnreadMessageCountWithSuccBlock:^(UInt64 totalCount) {
        [weakSelf onChangeUnReadCount:totalCount];
    } fail:nil];
    
    _unRead = [[TUIUnReadView alloc] init];

    if (![weakSelf.conversationData.userID isEqualToString:@"administrator"]) {
        UIButton *rightButton = [[UIButton alloc]initWithFrame:CGRectMake(0, 0, 30, 30)];
        [rightButton addTarget:self action:@selector(rightBarButtonClick) forControlEvents:UIControlEventTouchUpInside];
        [rightButton setImage:TUIChatBundleThemeImage(@"chat_nav_more_menu_img", @"chat_nav_more_menu") forState:UIControlStateNormal];
        [rightButton setTitleColor:[UIColor colorWithRed:102/255.0 green:102/255.0 blue:102/255.0 alpha:1.0] forState:UIControlStateNormal];
        rightButton.titleLabel.font = [UIFont boldSystemFontOfSize:16.0];
        UIBarButtonItem *rightItem = [[UIBarButtonItem alloc] initWithCustomView:rightButton];
        self.navigationItem.rightBarButtonItems = @[rightItem];
    }
    
    UIButton *leftButton = [[UIButton alloc]initWithFrame:CGRectMake(0, 0, 20, 30)];
    [leftButton addTarget:self action:@selector(leftBarButtonClick) forControlEvents:UIControlEventTouchUpInside];
    [leftButton setImage:[UIImage imageNamed:@"public_arrow_left"] forState:UIControlStateNormal];
    [leftButton setTitleColor:[UIColor colorWithRed:102/255.0 green:102/255.0 blue:102/255.0 alpha:1.0] forState:UIControlStateNormal];
    leftButton.titleLabel.font = [UIFont boldSystemFontOfSize:16.0];
    UIBarButtonItem *leftItem = [[UIBarButtonItem alloc] initWithCustomView:leftButton];
    self.navigationItem.leftBarButtonItems = @[leftItem];
}

- (void)setupMessageController {
    TUIMessageController *vc = [[TUIMessageController alloc] init];
    vc.hightlightKeyword = self.highlightKeyword;
    vc.locateMessage = self.locateMessage;
    vc.isMsgNeedReadReceipt = [TUIChatConfig defaultConfig].msgNeedReadReceipt;
    _messageController = vc;
    _messageController.delegate = self;
    [_messageController setConversation:self.conversationData];
    _messageController.view.frame = CGRectMake(0,  [self topMarginByCustomView],
                                               self.view.frame.size.width,
                                               self.view.frame.size.height - (TTextView_Height + Bottom_SafeHeight + kTTextViewBottomBar_Height) - [self topMarginByCustomView]);
    [self addChildViewController:_messageController];
    [self.view addSubview:_messageController.view];
    [_messageController didMoveToParentViewController:self];
}

- (void)setupCustomTopView {
    [self.view addSubview:customTopView];
    customTopView.mm_top(0).mm_left(0);
}

- (void)setupInputController {
    _inputController = [[TUIInputController alloc] init];
    _inputController.delegate = self;
    @weakify(self)
    [RACObserve(self, moreMenus) subscribeNext:^(NSArray *x) {
        @strongify(self)
        [self.inputController.moreView setData:x];
    }];
    _inputController.view.frame = CGRectMake(0, self.view.frame.size.height - (TTextView_Height + Bottom_SafeHeight + kTTextViewBottomBar_Height), self.view.frame.size.width, TTextView_Height + Bottom_SafeHeight + kTTextViewBottomBar_Height);
    _inputController.view.autoresizingMask = UIViewAutoresizingFlexibleTopMargin;
    [self addChildViewController:_inputController];
    [self.view addSubview:_inputController.view];
}

- (void)configBackgroundView {
    self.backgroudView = [[UIImageView alloc] init];
    self.backgroudView.backgroundColor = TUIChatConfig.defaultConfig.backgroudColor ? TUIChatConfig.defaultConfig.backgroudColor : TUIChatDynamicColor(@"chat_controller_bg_color", @"#FFFFFF");
    NSString *conversationID = [self getConversationID];
    NSString *imgUrl = [self getBackgroundImageUrlByConversationID:conversationID];

    if (TUIChatConfig.defaultConfig.backgroudImage) {
        self.backgroudView.backgroundColor = UIColor.clearColor;
        self.backgroudView.image = TUIChatConfig.defaultConfig.backgroudImage;
    }
    else if (IS_NOT_EMPTY_NSSTRING(imgUrl)) {
        [self.backgroudView sd_setImageWithURL:[NSURL URLWithString:imgUrl] placeholderImage:nil];
    }
    self.backgroudView.frame = CGRectMake(0, self.view.frame.origin.y, self.view.frame.size.width, self.view.frame.size.height - (TTextView_Height + Bottom_SafeHeight + kTTextViewBottomBar_Height));
    
    [self.view insertSubview:self.backgroudView atIndex:0];
    
    //使用自己的头像做背景图
    self.backgroudView.clipsToBounds = YES;
    self.backgroudView.contentMode = UIViewContentModeScaleAspectFill;
    self.backgroudView.backgroundColor = kBgGrayColor;
    if (self.conversationData.userID.length > 0 && ![self.conversationData.userID isEqualToString:@"administrator"]) {
        //代表单聊
        [self.backgroudView sd_setImageWithURL:[NSURL URLWithString:self.conversationData.faceUrl] placeholderImage:nil];
    }
    //毛玻璃遮罩
    UIBlurEffect *effect = [UIBlurEffect effectWithStyle:UIBlurEffectStyleDark];
    UIVisualEffectView *effectView = [[UIVisualEffectView alloc] initWithEffect:effect];
    effectView.alpha = 0.8;
    effectView.frame = CGRectMake(0, self.view.frame.origin.y, self.view.frame.size.width, self.view.frame.size.height - (TTextView_Height + Bottom_SafeHeight + kTTextViewBottomBar_Height));
    [self.backgroudView addSubview:effectView];
}

- (void)configNotify {

    [[V2TIMManager sharedInstance] addConversationListener:self];
    [[V2TIMManager sharedInstance] addGroupListener:self];

    [TUICore registerEvent:TUICore_TUIConversationNotify subKey:TUICore_TUIConversationNotify_SelectConversationSubKey object:self];
    [TUICore registerEvent:TUICore_TUIConversationNotify subKey:TUICore_TUIConversationNotify_ClearConversationUIHistorySubKey object:self];
    [NSNotificationCenter.defaultCenter addObserver:self selector:@selector(onFriendInfoChanged:) name:@"FriendInfoChangedNotification" object:nil];

    [TUICore registerEvent:TUICore_TUIContactNotify subKey:TUICore_TUIContactNotify_UpdateConversationBackgroundImageSubKey object:self];
    [TUICore registerEvent:TUICore_TUIGroupNotify subKey:TUICore_TUIGroupNotify_UpdateConversationBackgroundImageSubKey object:self];

}

#pragma mark - Request

//家族详情
//参数1：id 家族id 二选一
//参数2：familyId 家族familyId 二选一
- (void)requestGetFamilyDetailInfo {
    if (self.conversationData.groupID == nil || self.conversationData.groupID.length == 0) {
        return;
    }
    NSDictionary *dic = @{
        @"familyId":self.conversationData.groupID
    };
    MJWeakSelf
    [YBHttpRequest post:kAppUrl_getFamilyDetailInfo parameters:dic success:^(NSURLSessionDataTask * _Nullable task, id  _Nullable responseObject) {
        YBFamilyModel *model =[YBFamilyModel mj_objectWithKeyValues:responseObject[@"data"]];
        weakSelf.familyModel = model;
        [weakSelf.backgroudView sd_setImageWithURL:[NSURL URLWithString:model.pic] placeholderImage:nil];

        if ([kUserInfo.nobleid intValue] > 0 && !weakSelf.isShowNotice) {
            weakSelf.isShowNotice = true;
            [weakSelf requestInFamilyNotice];
        }
    } failure:^(NSURLSessionDataTask * _Nullable task, YBHttpRequestModel * _Nullable model) {
        [XNHUD showWithTitle:model.msg];
    } erronrous:^(NSURLSessionDataTask * _Nonnull task, NSError * _Nullable error) {
        [XNHUD showWithTitle:kNetErrorTip];
    }];
}

//进入家族入场通知
- (void)requestInFamilyNotice {
    if (self.familyModel == nil || self.familyModel.identify.length == 0) {
        return;
    }
    NSDictionary *dic = @{
        @"fid":self.familyModel.identify
    };
    [YBHttpRequest post:kAppUrl_inFamilyNotice parameters:dic success:^(NSURLSessionDataTask * _Nullable task, id  _Nullable responseObject) {

    } failure:^(NSURLSessionDataTask * _Nullable task, YBHttpRequestModel * _Nullable model) {

    } erronrous:^(NSURLSessionDataTask * _Nonnull task, NSError * _Nullable error) {

    }];
}

//查看某个用户的信息
- (void)requestUserInfo {
    if (self.conversationData.userID == nil || self.conversationData.userID.length == 0) {
        return;
    }

    NSDictionary *dic = @{
        @"userid":self.conversationData.userID
    };
    MJWeakSelf
    [YBHttpRequest post:kAppUrl_userLookTinfo parameters:dic success:^(NSURLSessionDataTask * _Nullable task, id  _Nullable responseObject) {
        YBLoginUserInfoModel *model = [YBLoginUserInfoModel mj_objectWithKeyValues:responseObject[@"data"]];
        weakSelf.friendInfoModel = model;
        
        [self.userInfoView.headImgV sd_setImageWithURL:[NSURL URLWithString:model.pic] placeholderImage:kDefaultHead];
        self.userInfoView.nameLab.text = model.nick;
        self.userInfoView.ageLab.text = [NSString stringWithFormat:@" %@岁 ",model.age];
        self.userInfoView.desLab.text = [NSString stringWithFormat:@"%@", model.mysign.length > 0 ? model.mysign:@"这个人很懒，什么也没留下"];

    } failure:^(NSURLSessionDataTask * _Nullable task, YBHttpRequestModel * _Nullable model) {
        [XNHUD showWithTitle:model.msg];
    } erronrous:^(NSURLSessionDataTask * _Nonnull task, NSError * _Nullable error) {
        [XNHUD showWithTitle:kNetErrorTip];
    }];
}

//获取与对方的亲密度
- (void)requestAppGuardGetToUserIntimacy {
    if (self.conversationData.userID == nil || self.conversationData.userID.length == 0) {
        return;
    }
    
    NSDictionary *dic = @{
        @"toTxCode":self.conversationData.userID
    };
    [YBHttpRequest post:kAppUrl_appGuardGetToUserIntimacy parameters:dic success:^(NSURLSessionDataTask * _Nullable task, id  _Nullable responseObject) {
        /**
         data =     {
         beiUserId = 3;
         createtime = "2022-12-26 10:31:27";
         giftMoney = 31;
         id = 10627;
         intimacy = "3.1";
         intimacyvoice = 0;
         isGuard = 2;
         userId = 7;
         };
         */
        if (responseObject[@"data"]) {
            float intimacy = [responseObject[@"data"][@"intimacy"] floatValue];
            self.intimacy = intimacy;
            self.intimacyIconView.titleLab.text = [NSString stringWithFormat:@"%.1f℃", intimacy];
        }
    } failure:^(NSURLSessionDataTask * _Nullable task, YBHttpRequestModel * _Nullable model) {
        
    } erronrous:^(NSURLSessionDataTask * _Nonnull task, NSError * _Nullable error) {
        
    }];
}

//是否是黑名单
- (void)requestAppuserisBlack {
    NSDictionary *dic = @{
        @"tengxuncode": self.conversationData.userID?self.conversationData.userID:@""
    };
    [YBHttpRequest post:kAppUrl_appuserisBlack parameters:dic success:^(NSURLSessionDataTask * _Nullable task, id  _Nullable responseObject) {
        /**
         data =     {
         free = 0;
         intimacy = "3.1";
         intimacyZuanshi = "0.1";
         intimacyvoice = 0;
         isBlack = 0;
         pic = "http://heibeikeji.oss-cn-shenzhen.aliyuncs.com/image/37df5013f8ad43ce8a8ed82bedb1c266.jpg";
         };
         */
        YBAppuserisBlackModel *blackModel = [YBAppuserisBlackModel mj_objectWithKeyValues:responseObject[@"data"]];
        float intimacy = [blackModel.intimacy floatValue];
        self.intimacy = intimacy;
        self.intimacyIconView.titleLab.text = [NSString stringWithFormat:@"%.1f℃", intimacy];
        self.messageController.blackModel = blackModel;
        self.blackModel = blackModel;
    } failure:^(NSURLSessionDataTask * _Nullable task, YBHttpRequestModel * _Nullable model) {
        
    } erronrous:^(NSURLSessionDataTask * _Nonnull task, NSError * _Nullable error) {
        
    }];
}

//送礼自定义数量
- (void)requestAppsonglisonglinumWithCellData:(YBGiftCellData *)cellData giftCount:(NSInteger)giftCount {
    NSDictionary *dic = @{
        @"userid": cellData.getGiftUserId?cellData.getGiftUserId:@"",
        @"giftid": cellData.giftsId?cellData.giftsId:@"",
        @"giftnum": @(giftCount),
    };
    [XNHUD showLoadingWithTitle:@""];
    [YBHttpRequest post:kAppUrl_appsonglisonglinum parameters:dic success:^(NSURLSessionDataTask * _Nullable task, id  _Nullable responseObject) {
        [XNHUD dismiss];
        NSDictionary *param = @{
            @"businessID" : BussinessID_GiveGift,
            @"img":cellData.img?cellData.img:@"",
            @"type":@"@@@@@***",
            @"giftsNum":@(giftCount),
            @"giftsName":cellData.giftsName?cellData.giftsName:@"",
            @"giftsId":cellData.giftsId?cellData.giftsId:@"",
            @"giftsPrice":cellData.giftsPrice?cellData.giftsPrice:@"",
            @"svgaUrl":cellData.svgaUrl?cellData.svgaUrl:@"",
            @"sendGiftUserId":cellData.sendGiftUserId?cellData.sendGiftUserId:@"",
            @"sendGiftUserName":cellData.sendGiftUserName?cellData.sendGiftUserName:@"",
            @"songliUserPic":cellData.songliUserPic?cellData.songliUserPic:@"",
            @"getGiftUserId":cellData.getGiftUserId?cellData.getGiftUserId:@"",
            @"getGiftUserName":cellData.getGiftUserName?cellData.getGiftUserName:@"",
            @"shouliUserPic":cellData.shouliUserPic?cellData.shouliUserPic:@"",
        };

        NSData *data = [NSJSONSerialization dataWithJSONObject:param options:0 error:nil];
        V2TIMMessage *message = [[V2TIMManager sharedInstance] createCustomMessage:data];
        [self sendMessage:message];

        //获取与对方的亲密度
        [self requestAppGuardGetToUserIntimacy];
        //SVGA动效
        [[YBGiftTool shareInstance] playSvgaWithDic:param];
        //飘屏动效
        [[YBGiftTool shareInstance] moveScreenWithDic:param type:YBMoveScreenTypeSendGift];
        
    } failure:^(NSURLSessionDataTask * _Nullable task, YBHttpRequestModel * _Nullable model) {
        [XNHUD showWithTitle:model.msg];
    } erronrous:^(NSURLSessionDataTask * _Nonnull task, NSError * _Nullable error) {
        [XNHUD dismiss];
    }];
}

////发送红包接口
////请求参数1：goldNum 红包玫瑰数量 必传
////请求参数2：redNum 红包数量 不传默认为1
////请求参数3：remark 备注
//static  NSString * _Nonnull  const  MDAPPURL_redPackSend= @"app/redPack/send";
- (void)redPackSendWithCoinCount:(NSString *)coinCount redBagCount:(NSString *)redBagCount auspiciousWords:(NSString *)auspiciousWords {
    //发红包请求接口，成功之后发送自定义红包消息
    NSDictionary *dic = @{
        @"goldNum": coinCount?coinCount:@"",
        @"redNum": redBagCount?redBagCount:@"1",
        @"remark": auspiciousWords?auspiciousWords:@"恭喜发财，大吉大利",
    };
    
    [YBHttpRequest post:kAppUrl_redPackSend parameters:dic success:^(NSURLSessionDataTask * _Nullable task, id  _Nullable responseObject) {
        
        if ([responseObject objectForKey:@"data"]) {
            NSDictionary *respData = responseObject[@"data"];
            NSString *remark = respData[@"remark"] ? respData[@"remark"] : @"恭喜发财，大吉大利";
            NSString *redBagId = respData[@"id"] ? respData[@"id"] : @"";
            
            //发红包
            NSDictionary *param = @{
                @"businessID" : BussinessID_RedPacket,
                @"message" : remark,
                @"userid" : kUserInfo.identify?kUserInfo.identify:@"",
                @"nick" : kUserInfo.nick?kUserInfo.nick:@"",
                @"pic" : kUserInfo.pic?kUserInfo.pic:@"",
                @"messageType" : @"266",
                @"TXuserId" : kUserInfo.tengxuncode?kUserInfo.tengxuncode:@"",
                @"redBagId" : redBagId,
            };
            
            NSData *data = [NSJSONSerialization dataWithJSONObject:param options:0 error:nil];
            V2TIMMessage *message = [[V2TIMManager sharedInstance] createCustomMessage:data];
            [self sendMessage:message];
        }
        
    } failure:^(NSURLSessionDataTask * _Nullable task, YBHttpRequestModel * _Nullable model) {
        [XNHUD showWithTitle:model.msg];
    } erronrous:^(NSURLSessionDataTask * _Nonnull task, NSError * _Nullable error) {
        
    }];
}

////领取红包接口
////请求参数1：reid 红包id 必传
//static  NSString * _Nonnull  const  MDAPPURL_redPackReceive= @"app/redPack/receive";
- (void)redPackReceiveWithReid:(YBRedEnvelopeCellData *)cellData {

    if (self.conversationData.groupID.length > 0 || !([cellData.userid isEqualToString:kUserInfo.identify])) {
        //发红包请求接口，成功之后发送自定义红包消息
        NSDictionary *dic = @{
            @"reid": cellData.redBagId?cellData.redBagId:@"",
        };
        
        MJWeakSelf
        [YBHttpRequest post:kAppUrl_redPackReceive parameters:dic success:^(NSURLSessionDataTask * _Nullable task, id  _Nullable responseObject) {
            
            YBReceiveRedEnvelopeVC *vv = [[YBReceiveRedEnvelopeVC alloc]init];
            vv.cellData = cellData;
            [weakSelf.navigationController pushViewController:vv animated:YES];
            
            [weakSelf redPackStatusWithDic:cellData];
        } failure:^(NSURLSessionDataTask * _Nullable task, YBHttpRequestModel * _Nullable model) {
            
            YBReceiveRedEnvelopeVC *vv = [[YBReceiveRedEnvelopeVC alloc]init];
            vv.cellData = cellData;
            [weakSelf.navigationController pushViewController:vv animated:YES];

        } erronrous:^(NSURLSessionDataTask * _Nonnull task, NSError * _Nullable error) {
            
        }];
    }else {
        YBReceiveRedEnvelopeVC *vv = [[YBReceiveRedEnvelopeVC alloc]init];
        vv.cellData = cellData;
        [self.navigationController pushViewController:vv animated:YES];
    }
}

////获取红包领取状态
////请求参数1：reid 红包id 必传
//static  NSString * _Nonnull  const  MDAPPURL_redPackStatus= @"app/redPack/status";
- (void)redPackStatusWithDic:(YBRedEnvelopeCellData *)cellData {
    //发红包请求接口，成功之后发送自定义红包消息
    NSDictionary *dic = @{
        @"reid": cellData.redBagId?cellData.redBagId:@"",
    };
    
    MJWeakSelf
    [YBHttpRequest post:kAppUrl_redPackStatus parameters:dic success:^(NSURLSessionDataTask * _Nullable task, id  _Nullable responseObject) {
        YBRedPackListModel *model = [YBRedPackListModel mj_objectWithKeyValues:responseObject[@"data"]];
        
        //抢红包成功后就发个自定义消息
        NSDictionary *param = @{
            @"businessID" : BussinessID_ReceiveRedPacket,
            @"getHbuserName" : kUserInfo.nick?kUserInfo.nick:@"",
            @"getHbuserId" : kUserInfo.identify?kUserInfo.identify:@"",
            @"sendHbUserName" : cellData.nick?cellData.nick:@"",
            @"sendHbUserId" : cellData.userid?cellData.userid:@"",
            @"count" : model.goldNum?model.goldNum:@"",
            @"messageType" : @"276",
        };
        
        NSData *data = [NSJSONSerialization dataWithJSONObject:param options:0 error:nil];
        V2TIMMessage *message = [[V2TIMManager sharedInstance] createCustomMessage:data];
        [weakSelf sendMessage:message];
        
    } failure:^(NSURLSessionDataTask * _Nullable task, YBHttpRequestModel * _Nullable model) {
        [XNHUD showWithTitle:model.msg];
    } erronrous:^(NSURLSessionDataTask * _Nonnull task, NSError * _Nullable error) {
        
    }];
}

#pragma mark - Public Methods

- (void)sendMessage:(V2TIMMessage *)message
{
    [self.messageController sendMessage:message];
}

- (void)saveDraft
{
    NSString *content = [self.inputController.inputBar.inputTextView.textStorage getPlainString];
    
    TUIReplyPreviewData * previewData = nil;
    if (self.inputController.referenceData) {
        previewData  = self.inputController.referenceData;
    }
    else if(self.inputController.replyData) {
        previewData  = self.inputController.replyData;
    }
    if (previewData) {
        
        NSDictionary *dict = @{
            @"content" : content?:@"",
            @"messageReply" : @{
                    @"messageID"       : previewData.msgID?:@"",
                    @"messageAbstract" : [previewData.msgAbstract?:@"" getInternationalStringWithfaceContent],
                    @"messageSender"   : previewData.sender?:@"",
                    @"messageType"     : @(previewData.type),
                    @"messageTime"     : @(previewData.originMessage.timestamp ? [previewData.originMessage.timestamp timeIntervalSince1970] : 0),  // Compatible for web
                    @"messageSequence" : @(previewData.originMessage.seq),// Compatible for web
                    @"version"         : @(kDraftMessageReplyVersion),
            },
        };
        NSMutableDictionary *mudic = [NSMutableDictionary dictionaryWithDictionary:dict];
        
        if (IS_NOT_EMPTY_NSSTRING(previewData.messageRootID)) {
            [mudic setObject:previewData.messageRootID forKey:@"messageRootID"];
        }
        NSError *error = nil;
        NSData *data = [NSJSONSerialization dataWithJSONObject:mudic options:0 error:&error];
        if (error == nil) {
            content = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding];
        }
    }
    [TUIChatDataProvider saveDraftWithConversationID:self.conversationData.conversationID Text:content];

}

- (void)loadDraft
{
    NSString *draft = self.conversationData.draftText;
    if (draft.length == 0) {
        return;
    }
    
    NSError *error = nil;
    NSDictionary *jsonDict = [NSJSONSerialization JSONObjectWithData:[draft dataUsingEncoding:NSUTF8StringEncoding] options:0 error:&error];
    if (error || jsonDict == nil) {
                
        NSMutableAttributedString *formatEmojiString = [draft getAdvancedFormatEmojiStringWithFont:kTUIInputNoramlFont textColor:kTUIInputNormalTextColor emojiLocations:nil];

        
        [self.inputController.inputBar.inputTextView.textStorage insertAttributedString:formatEmojiString atIndex:0];
        return;
    }
    
    /**
     * 显示草稿
     * Display draft
     */
    NSString *draftContent = [jsonDict.allKeys containsObject:@"content"] ? jsonDict[@"content"] : @"";
    
    NSMutableAttributedString *formatEmojiString = [draftContent getAdvancedFormatEmojiStringWithFont:kTUIInputNoramlFont textColor:kTUIInputNormalTextColor emojiLocations:nil];

    [self.inputController.inputBar.inputTextView.textStorage insertAttributedString:formatEmojiString atIndex:0];
    
    NSString *messageRootID = [jsonDict.allKeys containsObject:@"messageRootID"] ? jsonDict[@"messageRootID"] : @"";

    /**
     * 显示消息回复预览
     * Display message reply preview bar
     */
    if ([jsonDict isKindOfClass:NSDictionary.class] && [jsonDict.allKeys containsObject:@"messageReply"]) {
        NSDictionary *reply = jsonDict[@"messageReply"];
        if ([reply isKindOfClass:NSDictionary.class] &&
            [reply.allKeys containsObject:@"messageID"] &&
            [reply.allKeys containsObject:@"messageAbstract"] &&
            [reply.allKeys containsObject:@"messageSender"] &&
            [reply.allKeys containsObject:@"messageType"] &&
            [reply.allKeys containsObject:@"version"]) {
            NSInteger version = [reply[@"version"] integerValue];
            if (version <= kDraftMessageReplyVersion) {

                if (IS_NOT_EMPTY_NSSTRING(messageRootID)) {
                    TUIReplyPreviewData *replyData = [[TUIReplyPreviewData alloc] init];
                    replyData.msgID       = reply[@"messageID"];
                    replyData.msgAbstract = reply[@"messageAbstract"];
                    replyData.sender      = reply[@"messageSender"];
                    replyData.type        = [reply[@"messageType"] integerValue];
                    replyData.messageRootID = messageRootID;
                    [self.inputController showReplyPreview:replyData];
                }
                else {
                    TUIReferencePreviewData *replyData = [[TUIReferencePreviewData alloc] init];
                    replyData.msgID       = reply[@"messageID"];
                    replyData.msgAbstract = reply[@"messageAbstract"];
                    replyData.sender      = reply[@"messageSender"];
                    replyData.type        = [reply[@"messageType"] integerValue];
                    [self.inputController showReferencePreview:replyData];
                }
            }
        }
    }
}

+ (void)setCustomTopView:(UIView *)view {
    customTopView = view;
}

+ (UIView *)customTopView {
    return customTopView;
}

#pragma mark - Getters & Setters

- (void)setConversationData:(TUIChatConversationModel *)conversationData {
    _conversationData = conversationData;
    self.resgisterParam = [NSMutableArray array];
    _moreMenus = ({
        NSMutableArray<TUIInputMoreCellData *> *moreMenus = [TUIChatDataProvider moreMenuCellDataArray:conversationData.groupID userID:conversationData.userID isNeedVideoCall:[TUIChatConfig defaultConfig].enableVideoCall isNeedAudioCall:[TUIChatConfig defaultConfig].enableAudioCall isNeedGroupLive:NO isNeedLink:[TUIChatConfig defaultConfig].enableLink];
        moreMenus;
    });
    
}

- (CGFloat)topMarginByCustomView {
    return customTopView ? customTopView.mm_h: 0;
}

- (YBGiftVC *)yBGiftVC {
    if (!_yBGiftVC) {
        _yBGiftVC = [[YBGiftVC alloc]init];
        MJWeakSelf
        _yBGiftVC.yBGiftVCDismissBlock = ^{
            weakSelf.yBGiftVC = nil;
        };
    }
    return _yBGiftVC;
}

- (YBPlacetopView *)placetopView {
    if (!_placetopView) {
        _placetopView = [[[NSBundle mainBundle] loadNibNamed:@"YBPlacetopView" owner:self options:nil] lastObject];
        _placetopView.backgroundColor = kUIColorFromRGB(0xBA55D3);
        _placetopView.hidden = YES;
        
        [self.view addSubview:_placetopView];
        [_placetopView mas_makeConstraints:^(MASConstraintMaker *make) {
            make.top.offset(StatusBar_Height + NavBar_Height);
            make.left.right.offset(0);
            make.height.equalTo(@(70));
        }];
    }
    return _placetopView;
}

- (YBChatUserInfoView *)userInfoView {
    if (!_userInfoView) {
        _userInfoView = [[[NSBundle mainBundle] loadNibNamed:@"YBChatUserInfoView" owner:self options:nil] lastObject];
        MJWeakSelf
        _userInfoView.yBChatUserInfoViewBlock = ^{
            weakSelf.messageController.tableView.tableHeaderView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, kScreenWidth, 80)];
        };
        [self.view addSubview:_userInfoView];
        [_userInfoView mas_makeConstraints:^(MASConstraintMaker *make) {
            make.top.offset(kStatusBarHeight + NavBar_Height);
            make.left.right.offset(0);
            make.height.equalTo(@(110));
        }];
        self.messageController.tableView.tableHeaderView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, kScreenWidth, 110)];
    }
    return _userInfoView;
}

- (YBIntimacyIconView *)intimacyIconView {
    if (!_intimacyIconView) {
        _intimacyIconView = [[YBIntimacyIconView alloc]init];
        _intimacyIconView.frame = CGRectMake(self.view.width-90-20, self.view.height-kSafeAreaBottom-130-110-20, 90, 110);
        
        UIPanGestureRecognizer *pan = [[UIPanGestureRecognizer alloc] initWithTarget:self action:@selector(intimacyIconViewPan:)];
        [_intimacyIconView addGestureRecognizer:pan];
        UITapGestureRecognizer *tap = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(intimacyIconViewTap:)];
        [_intimacyIconView addGestureRecognizer:tap];
    }
    return _intimacyIconView;
}

#pragma mark - Event Response
- (void)onChangeUnReadCount:(UInt64)totalCount {
    /**
     * 此处异步的原因：当前聊天页面连续频繁收到消息，可能还没标记已读，此时也会收到未读数变更。理论上此时未读数不会包括当前会话的。
     * The reason for the asynchrony here: The current chat page receives messages continuously and frequently, it may not be marked as read, and unread changes will also be received at this time. In theory, the unreads at this time will not include the current session.
     */
    __weak typeof(self) weakSelf = self;
    dispatch_async(dispatch_get_main_queue(), ^{
        [weakSelf.unRead setNum:totalCount];
    });
}

- (void)checkTitle:(BOOL)force {
    
    if (force || self.conversationData.title.length == 0) {
        if (self.conversationData.userID.length > 0) {
            self.conversationData.title = self.conversationData.userID;
            @weakify(self);
            
            [TUIChatDataProvider getFriendInfoWithUserId:self.conversationData.userID
                                             SuccBlock:^(V2TIMFriendInfoResult * _Nonnull friendInfoResult) {
                @strongify(self);
                if (friendInfoResult.relation & V2TIM_FRIEND_RELATION_TYPE_IN_MY_FRIEND_LIST
                    && friendInfoResult.friendInfo.friendRemark.length > 0) {
                    self.conversationData.title = friendInfoResult.friendInfo.friendRemark;
                } else {
                    [TUIChatDataProvider getUserInfoWithUserId:friendInfoResult.friendInfo.userID
                                                   SuccBlock:^(V2TIMUserFullInfo * _Nonnull userInfo) {
                        if (userInfo.nickName.length > 0) {
                            self.conversationData.title = userInfo.nickName;
                        }
                    } failBlock:nil];
                }
            } failBlock:nil];
        }
        else if (self.conversationData.groupID.length > 0) {
            [TUIChatDataProvider getGroupInfoWithGroupID:self.conversationData.groupID
                                             SuccBlock:^(V2TIMGroupInfoResult * _Nonnull groupResult) {
                if (groupResult.info.groupName.length > 0) {
                    self.conversationData.title = groupResult.info.groupName;
                }
            } failBlock:nil];
        }
    }
}

-(void)leftBarButtonClick
{
    [self.navigationController popViewControllerAnimated:YES];
}

- (void)rightBarButtonClick
{
    if (_conversationData.userID.length > 0) {
        /**
        [self getUserOrFriendProfileVCWithUserID:self.conversationData.userID
                                       succBlock:^(UIViewController * _Nonnull vc) {
            [self.navigationController pushViewController:vc animated:YES];
        } failBlock:^(int code, NSString * _Nonnull desc) {
            [TUITool makeToastError:code msg:desc];
        }];
         */
        YBChatSetVC *vc = [[YBChatSetVC alloc]init];
        vc.userId = _conversationData.userID;
        [self.navigationController pushViewController:vc animated:YES];

    } else {
        /**
        NSDictionary *param = @{
            TUICore_TUIGroupService_GetGroupInfoControllerMethod_GroupIDKey: self.conversationData.groupID
        };
        UIViewController *vc = [TUICore callService:TUICore_TUIGroupService
                                             method:TUICore_TUIGroupService_GetGroupInfoControllerMethod
                                              param:param];
        [self.navigationController pushViewController:vc animated:YES];
         */
        
        YBFamilyDetailVC *vc =[YBFamilyDetailVC new];
        vc.familyModel = self.familyModel;
        [self.navigationController pushViewController:vc animated:YES];
    }
}

- (void)getUserOrFriendProfileVCWithUserID:(NSString *)userID
                                 succBlock:(void(^)(UIViewController *vc))succ
                                 failBlock:(nullable V2TIMFail)fail {
    NSDictionary *param = @{
        TUICore_TUIContactService_GetUserOrFriendProfileVCMethod_UserIDKey: userID ? : @"",
        TUICore_TUIContactService_GetUserOrFriendProfileVCMethod_SuccKey: succ ? : ^(UIViewController *vc){},
        TUICore_TUIContactService_GetUserOrFriendProfileVCMethod_FailKey: fail ? : ^(int code, NSString * desc){}
    };
    [TUICore callService:TUICore_TUIContactService
                  method:TUICore_TUIContactService_GetUserOrFriendProfileVCMethod
                   param:param];
}

// 亲密度拖拽事件
- (void)intimacyIconViewPan:(UIPanGestureRecognizer *)sender {
   //返回在横坐标上、纵坐标上拖动了多少像素
   CGPoint point = [sender translationInView:self.view];
   NSLog(@"%f,%f",point.x,point.y);
   
   CGFloat centerX = sender.view.center.x+point.x;
   CGFloat centerY = sender.view.center.y+point.y;
   CGSize viewSize = sender.view.frame.size;
   
   // top
   if (centerY - viewSize.height/2 < kNavigationBarHeight) {
       centerY = viewSize.height/2+kNavigationBarHeight;
   }
   // bottom
   if (centerY + viewSize.height/2 > kScreenHeight) {
       centerY = kScreenHeight - viewSize.height/2;
   }
   // left
   if (centerX - viewSize.width/2 < 0){
       centerX = viewSize.width/2;
   }
   // right
   if (centerX + viewSize.width/2 > kScreenWidth){
       centerX = kScreenWidth - viewSize.width/2;
   }
   sender.view.center = CGPointMake(centerX, centerY);
   //拖动完之后，每次都要用setTranslation:方法置0这样才不至于不受控制般滑动出视图
   [sender setTranslation:CGPointMake(0, 0) inView:self.view];
}

// 亲密度点击事件
- (void)intimacyIconViewTap:(UITapGestureRecognizer *)sender {
    if (self.blackModel) {
        NSString *avatarImgUrl = self.blackModel.pic;
        float intimacy = self.intimacy;
        float intimacyvoice = [self.blackModel.intimacyvoice floatValue];
        BOOL open1 = intimacy > intimacyvoice;
        BOOL open2 = self.blackModel.free;

        YBIntimacyAlertView *alertView = [[YBIntimacyAlertView alloc] initWithFrame:CGRectMake(0, 0, kScreenWidth, kScreenHeight) avatarImgUrl:avatarImgUrl intimacy:[NSString stringWithFormat:@"亲密度:%.1f℃", intimacy] open1:open1 open1Title:[NSString stringWithFormat:@"%.1f℃解锁语音和视频通话", intimacyvoice] open2:open2 open2Title:[NSString stringWithFormat:@"互相守护，语音、视频通话免费"]];
        [kWindow addSubview:alertView];
    }else{
        [self requestAppuserisBlack];
    }
}

#pragma mark - TUICore notify

- (void)onNotifyEvent:(NSString *)key subKey:(NSString *)subKey object:(id)anObject param:(NSDictionary *)param {
    if ([key isEqualToString:TUICore_TUIConversationNotify]
        && [subKey isEqualToString:TUICore_TUIConversationNotify_SelectConversationSubKey]
        && self.forwardConversationSelectVC == anObject) {
        NSArray<NSDictionary *> *selectList = param[TUICore_TUIConversationNotify_SelectConversationSubKey_ConversationListKey];
        
        NSMutableArray<TUIChatConversationModel *> *targetList = [NSMutableArray arrayWithCapacity:selectList.count];
        for (NSDictionary *selectItem in selectList) {
            TUIChatConversationModel *model = [TUIChatConversationModel new];
            model.title = selectItem[TUICore_TUIConversationNotify_SelectConversationSubKey_ItemTitleKey];
            model.userID = selectItem[TUICore_TUIConversationNotify_SelectConversationSubKey_ItemUserIDKey];
            model.groupID = selectItem[TUICore_TUIConversationNotify_SelectConversationSubKey_ItemGroupIDKey];
            model.conversationID = selectItem[TUICore_TUIConversationNotify_SelectConversationSubKey_ItemConversationIDKey];
            [targetList addObject:model];
        }
        
        [self forwardMessages:self.forwardSelectUIMsgs toTargets:targetList merge:self.isMergeForward];
        self.forwardSelectUIMsgs = nil;
    }
    
    else if ([key isEqualToString:TUICore_TUIConversationNotify] && [subKey isEqualToString:TUICore_TUIConversationNotify_ClearConversationUIHistorySubKey]) {
        [self.messageController clearUImsg];
    }
    else if ([key isEqualToString:TUICore_TUIContactNotify]
             && [subKey isEqualToString:TUICore_TUIContactNotify_UpdateConversationBackgroundImageSubKey]) {
        NSString *conversationID = param[TUICore_TUIContactNotify_UpdateConversationBackgroundImageSubKey_ConversationID];
        if (IS_NOT_EMPTY_NSSTRING(conversationID)) {
            [self updateBackgroundImageUrlByConversationID:conversationID];
        }
    }
    else if ([key isEqualToString:TUICore_TUIGroupNotify]
             && [subKey isEqualToString:TUICore_TUIGroupNotify_UpdateConversationBackgroundImageSubKey]) {
        NSString *conversationID = param[TUICore_TUIGroupNotify_UpdateConversationBackgroundImageSubKey_ConversationID];
        if (IS_NOT_EMPTY_NSSTRING(conversationID)) {
            [self updateBackgroundImageUrlByConversationID:conversationID];
        }
    }
    
}

- (void)updateBackgroundImageUrlByConversationID:(NSString *)conversationID {
    if ([[self getConversationID]  isEqualToString:conversationID]) {
        self.backgroudView.backgroundColor = UIColor.clearColor;
        NSString *imgUrl = [self getBackgroundImageUrlByConversationID:conversationID];
        if (IS_NOT_EMPTY_NSSTRING(imgUrl)) {
             [self.backgroudView sd_setImageWithURL:[NSURL URLWithString:imgUrl] placeholderImage:nil];
        }
        else {
            self.backgroudView.image = nil;
        }
    }
}

- (NSString *)getBackgroundImageUrlByConversationID:(NSString *)targerConversationID {
    if (targerConversationID.length == 0) {
        return nil;
    }
    NSDictionary *dict = [NSUserDefaults.standardUserDefaults objectForKey:@"conversation_backgroundImage_map"];
    if (dict == nil) {
        dict = @{};
    }
    NSString *conversationID_UserID = [NSString stringWithFormat:@"%@_%@",targerConversationID,[TUILogin getUserID]];
    if (![dict isKindOfClass:NSDictionary.class] || ![dict.allKeys containsObject:conversationID_UserID]) {
        return nil;
    }
    return [dict objectForKey:conversationID_UserID];
}

- (NSString *)getConversationID {
    NSString *conversationID = @"";
    if (self.conversationData.conversationID.length > 0) {
        conversationID = self.conversationData.conversationID;
    }
    else if (self.conversationData.userID.length > 0) {
        conversationID = [NSString stringWithFormat:@"c2c_%@",self.conversationData.userID];
    }
    else if (self.conversationData.groupID.length > 0) {
        conversationID = [NSString stringWithFormat:@"group_%@",self.conversationData.groupID];
    }
    return conversationID;
}

#pragma mark - TInputControllerDelegate
- (void)inputController:(TUIInputController *)inputController didChangeHeight:(CGFloat)height
{
    if (!self.responseKeyboard) {
        return;
    }
    [UIView animateWithDuration:0.3 delay:0 options:UIViewAnimationOptionCurveEaseOut animations:^{
        CGRect msgFrame = self.messageController.view.frame;
        msgFrame.size.height = self.view.frame.size.height - height - [self topMarginByCustomView];
        self.messageController.view.frame = msgFrame;

        CGRect inputFrame = self.inputController.view.frame;
        inputFrame.origin.y = msgFrame.origin.y + msgFrame.size.height;
        inputFrame.size.height = height;
        self.inputController.view.frame = inputFrame;
        [self.messageController scrollToBottom:NO];
    } completion:nil];
}

- (void)inputController:(TUIInputController *)inputController didSendMessage:(V2TIMMessage *)msg
{
    if (self.blackModel.isBlack) {
        [XNHUD showWithTitle:@"已被拉黑"];
        return;
    }
    
    if (msg.elemType == V2TIM_ELEM_TYPE_TEXT) {
        NSDictionary *dic = @{
            @"text": msg.textElem.text?msg.textElem.text:@"",
            @"topMsgFlag": @(inputController.inputBar.topSwitchButton.selected),
        };
        msg.textElem.text = dic.mj_JSONString;
    }
    [self.messageController sendMessage:msg];
}

- (void)inputControllerDidInputAt:(TUIInputController *)inputController
{
    /**
     * 交给 GroupChatVC 去处理
     * Handle to GroupChatVC
     */
}

- (void)inputController:(TUIInputController *)inputController didDeleteAt:(NSString *)atText
{
    /**
     * 交给 GroupChatVC 去处理
     * Handle to GroupChatVC
     */
}

- (void)inputControllerBeginTyping:(TUIInputController *)inputController {
    
    //for C2CChatVC
}

- (void)inputControllerEndTyping:(TUIInputController *)inputController {
    //for C2CChatVC
}

- (void)inputController:(TUIInputController *)inputController didSelectMoreCell:(TUIInputMoreCell *)cell
{
    if (self.blackModel.isBlack) {
        [XNHUD showWithTitle:@"已被拉黑"];
        return;
    }

    cell.disableDefaultSelectAction = NO;
    
    if (cell.disableDefaultSelectAction) {
        return;
    }
    if ([cell.data.key isEqualToString:[TUIInputMoreCellData photoData].key]) {
        [self selectPhotoForSendV2:NO];
    }
    else if ([cell.data.key isEqualToString:[TUIInputMoreCellData burnData].key]) {
        //发送阅后即焚图片
        [self selectPhotoForSendV2:YES];
    }
    else if ([cell.data.key isEqualToString:[TUIInputMoreCellData videoData].key]) {
        [self takeVideoForSend:NO];
    }
    else if ([cell.data.key isEqualToString:[TUIInputMoreCellData pictureData].key]) {
        [self takePictureForSend:NO];
    }
    else if ([cell.data.key isEqualToString:[TUIInputMoreCellData fileData].key]) {
        [self selectFileForSend];
    }
}

/**
 *  点击红包按钮，即“🧧”图标后的回调。
 *  您可以通过该回调实现：发送红包IM消息
 */
- (void)inputController:(TUIInputController *)inputController inputBarDidTouchRedEnvelope:(TUIInputBar *)textView {
    if (self.blackModel.isBlack) {
        [XNHUD showWithTitle:@"已被拉黑"];
        return;
    }
    
    YBRedEnvelopeVC *vc = [[YBRedEnvelopeVC alloc]init];
    vc.isSingle = self.conversationData.groupID.length == 0;
    MJWeakSelf
    vc.yBRedEnvelopeVCBlock = ^(NSString * _Nonnull coinCount, NSString * _Nonnull redBagCount, NSString * _Nonnull auspiciousWords) {
        
        [weakSelf redPackSendWithCoinCount:coinCount redBagCount:redBagCount auspiciousWords:auspiciousWords];
        
    };
    vc.modalPresentationStyle = UIModalPresentationOverCurrentContext;
    [self presentViewController:vc animated:YES completion:nil];
}

/**
 *  点击语音通话/视频通话按钮，即“☎️”图标后的回调。
 *  您可以通过该回调实现：发送语音通话/视频通话
 */
- (void)inputController:(TUIInputController *)inputController inputBarDidTouchCall:(TUIInputBar *)textView {
    if (self.blackModel.isBlack) {
        [XNHUD showWithTitle:@"已被拉黑"];
        return;
    }
    
    YBChatCallAlertView *alertView = [[YBChatCallAlertView alloc] initWithFrame:CGRectMake(0, 0, kScreenWidth, kScreenHeight)];
    [kWindow addSubview:alertView];
    //1语音通话 2视频通话
    MJWeakSelf;
    alertView.yBChatCallAlertViewBlock = ^(NSInteger type) {
        if (type == 1) {
            [[TUICallKit createInstance] call:weakSelf.conversationData.userID    callMediaType:TUICallMediaTypeAudio];
        }else if (type == 2) {
            [[TUICallKit createInstance] call:weakSelf.conversationData.userID    callMediaType:TUICallMediaTypeVideo];
        }
    };
}

/**
 *  点击礼物按钮，即“🎁”图标后的回调。
 *  您可以通过该回调实现：发送礼物消息
 */
- (void)inputController:(TUIInputController *)inputController inputBarDidTouchGift:(TUIInputBar *)textView {
    if (self.blackModel.isBlack) {
        [XNHUD showWithTitle:@"已被拉黑"];
        return;
    }
    
    [self messageSendGift:nil];
}

/**
 *  点击置顶按钮，即“开关”图标后的回调。
 *  您可以通过该回调实现：发送置顶消息
 */
- (void)inputController:(TUIInputController *)inputController inputBarDidTouchTopSwitch:(TUIInputBar *)textView {
    
}

/**
 *  点击常用语按钮，即“...”图标后的回调。
 *  您可以通过该回调实现：发送常用语消息
 */
- (void)inputController:(TUIInputController *)inputController inputBarDidTouchChatMsg:(TUIInputBar *)textView {
    if (self.blackModel.isBlack) {
        [XNHUD showWithTitle:@"已被拉黑"];
        return;
    }
    
    YBCommonWordsVC *vc = [[YBCommonWordsVC alloc]init];
    vc.sex = [NSString stringWithFormat:@"%@",self.friendInfoModel.sex];
    MJWeakSelf
    vc.yBCommonWordsVCBlock = ^(YBExpressionModel * _Nonnull model) {
        V2TIMMessage *message = [[V2TIMManager sharedInstance] createTextMessage:model.content];
        [weakSelf sendMessage:message];
    };
    YBBaseNavigationController *nav = [YBBaseNavigationController.alloc initWithRootViewController:vc];
    nav.modalTransitionStyle = UIModalTransitionStyleCrossDissolve;
    nav.modalPresentationStyle = UIModalPresentationOverCurrentContext;
    [self.navigationController presentViewController:nav animated:YES completion:nil];
}

#pragma mark - TUIBaseMessageControllerDelegate
- (void)didTapInMessageController:(TUIBaseMessageController *)controller
{
    [self.inputController reset];
}

- (BOOL)messageController:(TUIBaseMessageController *)controller willShowMenuInCell:(TUIMessageCell *)cell
{
    if([self.inputController.inputBar.inputTextView isFirstResponder]){
        self.inputController.inputBar.inputTextView.overrideNextResponder = cell;
        return YES;
    }
    return NO;
}

- (TUIMessageCellData *)messageController:(TUIBaseMessageController *)controller onNewMessage:(V2TIMMessage *)message
{
    return nil;
}

- (TUIMessageCell *)messageController:(TUIBaseMessageController *)controller onShowMessageData:(TUIMessageCellData *)data
{
    return nil;
}

- (void)messageController:(TUIBaseMessageController *)controller willDisplayCell:(TUIMessageCell *)cell withData:(TUIMessageCellData *)cellData {
    if([cell isKindOfClass:[TUIJoinGroupMessageCell class]]){
        TUIJoinGroupMessageCell *joinCell = (TUIJoinGroupMessageCell *)cell;
        joinCell.joinGroupDelegate = self;
    }
    else if ([cell isKindOfClass:[YBGiftCell class]]) {
        YBGiftCell *giftCell = (YBGiftCell *)cell;
        giftCell.yBGiftCellDelegate = self;
    }
    else if ([cell isKindOfClass:[TUITextMessageCell class]]) {
        TUITextMessageCell *textCell = (TUITextMessageCell *)cell;
        TUITextMessageCellData *textCellData = textCell.textData;
        if (textCellData.topMsgFlag) {
            //时间戳对比
            if (self.lastTextCellData) {
                int lastTimestamp = [self.lastTextCellData.innerMessage.timestamp timeIntervalSince1970];
                int currentTimestamp = [textCellData.innerMessage.timestamp timeIntervalSince1970];

                if (currentTimestamp > lastTimestamp) {
                    //展示并赋值
                    self.lastTextCellData = textCellData;
                    [NSObject cancelPreviousPerformRequestsWithTarget:self];
                    [self performSelector:@selector(showTopView) withObject:nil afterDelay:1.0];
                }
            }else {
                //展示并赋值
                self.lastTextCellData = textCellData;
                [NSObject cancelPreviousPerformRequestsWithTarget:self];
                [self performSelector:@selector(showTopView) withObject:nil afterDelay:1.0];
            }
        }
    }
}

/**
 *  点击消息头像委托
 *  您可以通过该回调实现：跳转到对应用户的详细信息界面。
 *  1、首先拉取用户信息，如果该用户是当前使用者好友，则初始化相应的好友信息界面并进行跳转。
 *  2、如果该用户不是当前使用者好友，则初始化相应的添加好友界面并进行跳转。
 *
 *  Callback for clicking avatar in the message cell
 *  You can use this callback to achieve: jump to the detailed information interface of the corresponding user.
 *  1. First pull user information, if the user is a friend of the current user, initialize the corresponding friend information interface and jump.
 *  2. If the user is not a friend of the current user, the corresponding interface for adding friends is initialized and a jump is performed.
 *
 */
- (void)messageController:(TUIBaseMessageController *)controller onSelectMessageAvatar:(TUIMessageCell *)cell
{
    if (cell.messageData.identifier == nil) {
        return;
    }
    /**
    [self getUserOrFriendProfileVCWithUserID:cell.messageData.identifier
                                   succBlock:^(UIViewController *vc) {
        [self.navigationController pushViewController:vc animated:YES];
    } failBlock:nil];
     */
    
    if (cell.messageData.direction == MsgDirectionOutgoing) {
        return;
    }
    if (self.conversationData.groupID.length > 0) {
        YBUserInfoAlertVC *vc = [[YBUserInfoAlertVC alloc]init];
        vc.modalPresentationStyle = UIModalPresentationOverCurrentContext;
        vc.alertVCType = YBUserInfoAlertVCTypeChat;
        vc.txCode = cell.messageData.identifier;
        /// 1000主页、1001举报、1002艾特Ta、1003私信、1004关注、1005送礼
        /// 2000抱麦、2001禁言、2002踢出房间
        MJWeakSelf
        vc.yBUserInfoAlertVCBlock = ^(UIButton * _Nonnull btn, id  _Nonnull model) {
            YBLoginUserInfoModel *loginUserInfoModel = (YBLoginUserInfoModel *)model;
            if (btn.tag == 1002) {
                [weakSelf.inputController.inputBar.inputTextView becomeFirstResponder];
                
                NSString *text = self.inputController.inputBar.inputTextView.text;
                NSString *str = [NSString stringWithFormat:@"@%@ ",loginUserInfoModel.nick];
                if ([text containsString:str]) {
                    return;
                }
                
                weakSelf.inputController.inputBar.inputTextView.text = [NSString stringWithFormat:@"%@%@",text,str];
                
            }else if (btn.tag == 1005) {
                [weakSelf.navigationController dismissViewControllerAnimated:YES completion:^{
                    [weakSelf messageSendGift:loginUserInfoModel];
                }];
            }
        };
        [self.navigationController presentViewController:vc animated:YES completion:nil];
    }else {
        YBUserInfoDetailVC *vc = [[YBUserInfoDetailVC alloc]init];
        vc.userId = cell.messageData.identifier;
        [self.navigationController pushViewController:vc animated:YES];
    }
}

/**
 *  长按消息头像委托
 *  Callback for long pressing avatar in the message cell
 */
- (void)messageController:(TUIBaseMessageController *)controller onLongSelectMessageAvatar:(TUIMessageCell *)cell {

}

- (void)messageController:(TUIBaseMessageController *)controller onSelectMessageContent:(TUIMessageCell *)cell
{
    cell.disableDefaultSelectAction = NO;
    if (cell.disableDefaultSelectAction) {
        return;
    }
    
    if ([cell isKindOfClass:[YBRedEnvelopeCell class]]) {
        [self clickRedEnvelopeMessage:(YBRedEnvelopeCell *)cell];
    }
    if ([cell isKindOfClass:[YBBurnAfterReadingCell class]]) {
        [self clickBurnAfterReadingMessage:(YBBurnAfterReadingCell *)cell];
    }
}

- (void)messageController:(TUIBaseMessageController *)controller onSelectMessageMenu:(NSInteger)menuType withData:(TUIMessageCellData *)data
{
    [self onSelectMessageMenu:menuType withData:data];
}

- (void)didHideMenuInMessageController:(TUIBaseMessageController *)controller
{
    self.inputController.inputBar.inputTextView.overrideNextResponder = nil;
}

- (void)messageController:(TUIBaseMessageController *)controller onReEditMessage:(TUIMessageCellData *)data
{
    V2TIMMessage *message = data.innerMessage;
    if (message.elemType == V2TIM_ELEM_TYPE_TEXT) {
        NSString *text = message.textElem.text;
        self.inputController.inputBar.inputTextView.text = text;
        [self.inputController.inputBar.inputTextView becomeFirstResponder];
    }
}

- (CGFloat)getTopMarginByCustomView {
    return [self topMarginByCustomView];
}

#pragma mark - TUIChatDataProviderForwardDelegate
- (NSString *)dataProvider:(TUIChatDataProvider *)dataProvider mergeForwardTitleWithMyName:(NSString *)name {
    return [self forwardTitleWithMyName:name];
}

- (NSString *)dataProvider:(TUIChatDataProvider *)dataProvider mergeForwardMsgAbstactForMessage:(V2TIMMessage *)message {
    return @"";
}

#pragma mark - TUINavigationControllerDelegate
- (void)navigationControllerDidClickLeftButton:(TUINavigationController *)controller {
    if (controller.currentShowVC == self) {
        [self.messageController readReport];
    }
}

- (void)navigationControllerDidSideSlideReturn:(TUINavigationController *)controller
                            fromViewController:(UIViewController *)fromViewController {
    if ([fromViewController isEqual:self]) {
        [self.messageController readReport];
    }
}

#pragma mark - 消息菜单操作: 多选 & 转发
- (void)onSelectMessageMenu:(NSInteger)menuType withData:(TUIMessageCellData *)data {
    if (menuType == 0) {
        [self openMultiChooseBoard:YES];
    } else if (menuType == 1) {
        if (data == nil) {
            return;
        }
        NSMutableArray *uiMsgs = [NSMutableArray arrayWithArray:@[data]];
        [self prepareForwardMessages:uiMsgs];
    }
}

- (void)openMultiChooseBoard:(BOOL)open
{
    [self.view endEditing:YES];
    
    if (_multiChooseView) {
        [_multiChooseView removeFromSuperview];
    }
    
    if (open) {
        _multiChooseView = [[TUIMessageMultiChooseView alloc] init];
        _multiChooseView.frame = UIScreen.mainScreen.bounds;
        _multiChooseView.delegate = self;
        _multiChooseView.titleLabel.text = self.conversationData.title;
        if (@available(iOS 12.0, *)) {
            if (@available(iOS 13.0, *)) {
                // > ios 12
                [UIApplication.sharedApplication.keyWindow addSubview:_multiChooseView];
            } else {
                // ios = 12
                UIView *view = self.navigationController.view;
                if (view == nil) {
                    view = self.view;
                }
                [view addSubview:_multiChooseView];
            }
        } else {
            // < ios 12
            [UIApplication.sharedApplication.keyWindow addSubview:_multiChooseView];
        }
    } else {
        [self.messageController enableMultiSelectedMode:NO];
    }
}

- (void)messageMultiChooseViewOnCancelClicked:(TUIMessageMultiChooseView *)multiChooseView
{
    [self openMultiChooseBoard:NO];
    [self.messageController enableMultiSelectedMode:NO];
}

- (void)messageMultiChooseViewOnRelayClicked:(TUIMessageMultiChooseView *)multiChooseView
{
    NSArray *uiMsgs = [self.messageController multiSelectedResult:TUIMultiResultOptionAll];
    [self prepareForwardMessages:uiMsgs];
}

- (void)messageMultiChooseViewOnDeleteClicked:(TUIMessageMultiChooseView *)multiChooseView
{
    NSArray *uiMsgs = [self.messageController multiSelectedResult:TUIMultiResultOptionAll];
    if (uiMsgs.count == 0) {
        [TUITool makeToast:TUIKitLocalizableString(TUIKitRelayNoMessageTips)];
        return;
    }
    
    [self.messageController deleteMessages:uiMsgs];
    [self openMultiChooseBoard:NO];
    [self.messageController enableMultiSelectedMode:NO];
}

- (void)prepareForwardMessages:(NSArray<TUIMessageCellData *> *)uiMsgs
{
    if (uiMsgs.count == 0) {
        [TUITool makeToast:TUIKitLocalizableString(TUIKitRelayNoMessageTips)];
        return;
    }

    BOOL hasUnsupportMsg = NO;
    for (TUIMessageCellData *data in uiMsgs) {
        if (data.status != Msg_Status_Succ) {
            hasUnsupportMsg = YES;
            break;
        }
    }
    
    if (hasUnsupportMsg) {
        UIAlertController *vc = [UIAlertController alertControllerWithTitle:TUIKitLocalizableString(TUIKitRelayUnsupportForward) message:nil preferredStyle:UIAlertControllerStyleAlert];
        [vc tuitheme_addAction:[UIAlertAction actionWithTitle:TUIKitLocalizableString(Confirm) style:UIAlertActionStyleDefault handler:^(UIAlertAction * _Nonnull action) {
            
        }]];
        [self presentViewController:vc animated:YES completion:nil];
        return;
    }
    
    __weak typeof(self) weakSelf = self;
    void(^chooseTarget)(BOOL) = ^(BOOL mergeForward) {
        UIViewController * vc = (UIViewController *)[TUICore callService:TUICore_TUIConversationService method:TUICore_TUIConversationService_GetConversationSelectControllerMethod param:nil];
        UINavigationController *nav = [[UINavigationController alloc] initWithRootViewController:(UIViewController *)vc];
        nav.modalPresentationStyle = UIModalPresentationFullScreen;
        weakSelf.forwardConversationSelectVC = (UIViewController *)vc;
        weakSelf.forwardSelectUIMsgs = uiMsgs;
        weakSelf.isMergeForward = mergeForward;
        [weakSelf presentViewController:nav animated:YES completion:nil];
    };
    
    UIAlertController *tipsVc = [UIAlertController alertControllerWithTitle:nil message:nil preferredStyle:UIAlertControllerStyleActionSheet];
    
    /**
     * 逐条转发
     * Forward one-by-one
     */
    [tipsVc tuitheme_addAction:[UIAlertAction actionWithTitle:TUIKitLocalizableString(TUIKitRelayOneByOneForward) style:UIAlertActionStyleDefault handler:^(UIAlertAction * _Nonnull action) {
        if (uiMsgs.count <= 30) {
            chooseTarget(NO);
            return;
        }
        UIAlertController *vc = [UIAlertController alertControllerWithTitle:TUIKitLocalizableString(TUIKitRelayOneByOnyOverLimit) message:nil preferredStyle:UIAlertControllerStyleAlert];
        [vc tuitheme_addAction:[UIAlertAction actionWithTitle:TUIKitLocalizableString(Cancel) style:UIAlertActionStyleDefault handler:nil]];
        [vc tuitheme_addAction:[UIAlertAction actionWithTitle:TUIKitLocalizableString(TUIKitRelayCombineForwad) style:UIAlertActionStyleDefault handler:^(UIAlertAction * _Nonnull action) {
            chooseTarget(YES);
        }]];
        [weakSelf presentViewController:vc animated:YES completion:nil];
    }]];
    
    /**
     * 合并转发
     * Merge-forward
     */
    [tipsVc tuitheme_addAction:[UIAlertAction actionWithTitle:TUIKitLocalizableString(TUIKitRelayCombineForwad) style:UIAlertActionStyleDefault handler:^(UIAlertAction * _Nonnull action) {
        chooseTarget(YES);
    }]];
    [tipsVc tuitheme_addAction:[UIAlertAction actionWithTitle:TUIKitLocalizableString(Cancel) style:UIAlertActionStyleDefault handler:nil]];
    [self presentViewController:tipsVc animated:YES completion:nil];
}

- (void)forwardMessages:(NSArray<TUIMessageCellData *> *)uiMsgs
              toTargets:(NSArray<TUIChatConversationModel *> *)targets
                  merge:(BOOL)merge
{
    if (uiMsgs.count == 0 || targets.count == 0) {
        return ;
    }
    
    @weakify(self);
    [self.dataProvider getForwardMessageWithCellDatas:uiMsgs
                                            toTargets:targets
                                                Merge:merge
                                          ResultBlock:^(TUIChatConversationModel * _Nonnull targetConversation, NSArray<V2TIMMessage *> * _Nonnull msgs) {
        @strongify(self);
        
        TUIChatConversationModel *convCellData = targetConversation;
        NSTimeInterval timeInterval = convCellData.groupID.length?0.09:0.05;
        
        /**
         * 发送到当前聊天窗口
         * Forward to currernt chat vc
         */
        if ([convCellData.conversationID isEqualToString:self.conversationData.conversationID]) {
            for (V2TIMMessage *imMsg in msgs) {
                dispatch_async(dispatch_get_main_queue(), ^{
                    /**
                     * 下面的函数涉及到 UI 的刷新，要放在主线程操作
                     * The following functions involve the refresh of the UI and should be called on the main thread
                     */
                    [self.messageController sendMessage:imMsg];
                });
                
                /**
                 * 此处的延时操作是为了在批量逐条转发时，尽可能保证接收端的顺序
                 * The delay here is to ensure the order of the receiving end as much as possible when forwarding in batches one by one
                 */
                [NSThread sleepForTimeInterval:timeInterval];
            }
            return;
        }
        
        /**
         * 发送到其他聊天
         * Forward to other chat user
         */
        for (V2TIMMessage *message in msgs) {
            message.needReadReceipt = [TUIChatConfig defaultConfig].msgNeedReadReceipt;
            [TUIMessageDataProvider sendMessage:message
                                 toConversation:convCellData
                                 isSendPushInfo:YES
                               isOnlineUserOnly:NO
                                       priority:V2TIM_PRIORITY_NORMAL
                                       Progress:nil
                                      SuccBlock:^{
                /**
                 * 发送到其他聊天的消息需要广播消息发送状态，方便进入对应聊天后刷新消息状态
                 * Messages sent to other chats need to broadcast the message sending status, which is convenient to refresh the message status after entering the corresponding chat
                 */
                [NSNotificationCenter.defaultCenter postNotificationName:TUIKitNotification_onMessageStatusChanged object:message.msgID];
            } FailBlock:^(int code, NSString *desc) {
                [NSNotificationCenter.defaultCenter postNotificationName:TUIKitNotification_onMessageStatusChanged object:message.msgID];
            }];
            
            /**
             * 此处的延时操作是为了在批量逐条转发时，尽可能保证接收端的顺序
             * The delay here is to ensure the order of the receiving end as much as possible when forwarding in batches one by one
             */
            [NSThread sleepForTimeInterval:timeInterval];
        }
    } fail:^(int code, NSString *desc) {
        NSLog(@"%@", desc);
        NSAssert(NO, desc);
    }];
}

- (NSString *)forwardTitleWithMyName:(NSString *)nameStr
{
    return @"";
}

#pragma mark - Message reply
- (void)messageController:(TUIBaseMessageController *)controller onRelyMessage:(nonnull TUIMessageCellData *)data
{
    @weakify(self)
    [self.inputController exitReplyAndReference:^{
        @strongify(self)
        NSString *desc = @"";
        desc = [self replyReferenceMessageDesc:data];
        
        TUIReplyPreviewData *replyData = [[TUIReplyPreviewData alloc] init];
        replyData.msgID = data.msgID;
        replyData.msgAbstract = desc;
        replyData.sender = data.name;
        replyData.type = (NSInteger)data.innerMessage.elemType;
        replyData.originMessage = data.innerMessage;
        
        NSMutableDictionary *cloudResultDic = [[NSMutableDictionary alloc] initWithCapacity:5];
        if (replyData.originMessage.cloudCustomData) {
            NSDictionary * originDic = [TUITool jsonData2Dictionary:replyData.originMessage.cloudCustomData];
            if (originDic && [originDic isKindOfClass:[NSDictionary class]]) {
                [cloudResultDic addEntriesFromDictionary:originDic];
            }
        }
        NSString * messageParentReply = cloudResultDic[@"messageReply"];
        NSString * messageRootID = [messageParentReply valueForKey:@"messageRootID"];
        if (!IS_NOT_EMPTY_NSSTRING(messageRootID)) {
            /**
             * 源消息没有 messageRootID， 则需要将当前源消息的 msgID 作为 root
             * If the original message does not have messageRootID, you need to make the msgID of the current original message as the root
             */
            if (IS_NOT_EMPTY_NSSTRING(replyData.originMessage.msgID)) {
                messageRootID = replyData.originMessage.msgID;
            }
        }
        
        replyData.messageRootID =  messageRootID;
        [self.inputController showReplyPreview:replyData];
    }];
    
}
- (NSString *)replyReferenceMessageDesc:(TUIMessageCellData *)data {
    NSString *desc = @"";
    if (data.innerMessage.elemType == V2TIM_ELEM_TYPE_FILE) {
        desc = data.innerMessage.fileElem.filename;
    } else if (data.innerMessage.elemType == V2TIM_ELEM_TYPE_MERGER) {
        desc = data.innerMessage.mergerElem.title;
    } else if (data.innerMessage.elemType == V2TIM_ELEM_TYPE_CUSTOM) {
        desc = [TUIMessageDataProvider getDisplayString:data.innerMessage];
    } else if (data.innerMessage.elemType == V2TIM_ELEM_TYPE_TEXT) {
        desc = data.innerMessage.textElem.text;
    }
    return desc;
}
#pragma mark - Message quote
- (void)messageController:(TUIBaseMessageController *)controller onReferenceMessage:(TUIMessageCellData *)data {
    @weakify(self)
    [self.inputController exitReplyAndReference:^{
        @strongify(self)
        NSString *desc = @"";
        desc = [self replyReferenceMessageDesc:data];
        
        TUIReferencePreviewData *referenceData = [[TUIReferencePreviewData alloc] init];
        referenceData.msgID = data.msgID;
        referenceData.msgAbstract = desc;
        referenceData.sender = data.name;
        referenceData.type = (NSInteger)data.innerMessage.elemType;
        referenceData.originMessage = data.innerMessage;
        [self.inputController showReferencePreview:referenceData];
    }];
    
}

#pragma mark - Message react
/*
 "messageReact": {
     "reacts": [
         {
             "emojiId1": ["userId1","userId2"]
         },
         {
             "emojiId2": ["userId3","userId4"]
         },
     ],
     "version": "1",
 }
 */
- (void)messageController:(TUIBaseMessageController *)controller modifyMessage:(nonnull TUIMessageCellData *)cellData reactEmoji:(NSString *)emojiName{
    
    V2TIMMessage *rootMsg = cellData.innerMessage;

    [[TUIChatModifyMessageHelper defaultHelper] modifyMessage:rootMsg reactEmoji:emojiName];
}
#pragma mark - Privete Methods
+ (void)createCachePath
{
    NSFileManager *fileManager = [NSFileManager defaultManager];
    if(![fileManager fileExistsAtPath:TUIKit_Image_Path]){
        [fileManager createDirectoryAtPath:TUIKit_Image_Path withIntermediateDirectories:YES attributes:nil error:nil];
    }
    if(![fileManager fileExistsAtPath:TUIKit_Video_Path]){
        [fileManager createDirectoryAtPath:TUIKit_Video_Path withIntermediateDirectories:YES attributes:nil error:nil];
    }
    if(![fileManager fileExistsAtPath:TUIKit_Voice_Path]){
        [fileManager createDirectoryAtPath:TUIKit_Voice_Path withIntermediateDirectories:YES attributes:nil error:nil];
    }
    if(![fileManager fileExistsAtPath:TUIKit_File_Path]){
        [fileManager createDirectoryAtPath:TUIKit_File_Path withIntermediateDirectories:YES attributes:nil error:nil];
    }
    if(![fileManager fileExistsAtPath:TUIKit_DB_Path]){
        [fileManager createDirectoryAtPath:TUIKit_DB_Path withIntermediateDirectories:YES attributes:nil error:nil];
    }
}

// 点击红包
- (void)clickRedEnvelopeMessage:(YBRedEnvelopeCell *)cell {
    YBRedEnvelopeCellData *cellData = cell.customData;

    [self redPackReceiveWithReid:cellData];
}

// 点击阅后即焚
- (void)clickBurnAfterReadingMessage:(YBBurnAfterReadingCell *)cell {
    YBBurnAfterReadingCellData *cellData = cell.customData;
    YBBurnAfterReadingVC *vc = [[YBBurnAfterReadingVC alloc]init];
    vc.cellData = cellData;
    vc.modalPresentationStyle = UIModalPresentationOverCurrentContext;
    [self presentViewController:vc animated:NO completion:nil];
}

//送礼礼物
- (void)messageSendGift:(YBLoginUserInfoModel *)friendInfoModel {
    //判断是群聊还是单聊
    if (self.conversationData.groupID.length > 0) {
        self.yBGiftVC.familyid = self.familyModel.familyid;
        self.yBGiftVC.ySSendGiftType = YSSendGiftFamilyType;
        //如果是点击头像
        if (friendInfoModel && [friendInfoModel isKindOfClass:[YBLoginUserInfoModel class]]) {
            YBGiftUserModel *userModel = [[YBGiftUserModel alloc]init];
            userModel.userId = friendInfoModel.identify;
            userModel.userName = friendInfoModel.nick;
            userModel.userAvatar = friendInfoModel.pic;
            userModel.isSelected = true;
            self.yBGiftVC.userArr = [NSMutableArray arrayWithArray:@[userModel]];
        }
        MJWeakSelf
        self.yBGiftVC.yBGiftVCSelectMoreBlock = ^{
            YBChooseWhoToGiftVC *chooseWhoToGiftVC = [[YBChooseWhoToGiftVC alloc] init];
            chooseWhoToGiftVC.familyId = weakSelf.familyModel.identify;
            chooseWhoToGiftVC.yBChooseWhoToGiftVCBlock = ^(NSArray<YBFamilyMemberModel *> * _Nonnull array) {
                NSMutableArray *mutArr = [NSMutableArray array];
                for (YBFamilyMemberModel *model in array) {
                    YBGiftUserModel *userModel = [[YBGiftUserModel alloc]init];
                    userModel.userId = model.userid;
                    userModel.userName = model.nick;
                    userModel.userAvatar = model.pic;
                    userModel.isSelected = YES;
                    [mutArr addObject:userModel];
                }
                weakSelf.yBGiftVC.userArr = mutArr;
            };
            YBBaseNavigationController *nav =[[YBBaseNavigationController alloc] initWithRootViewController:chooseWhoToGiftVC];
            nav.modalPresentationStyle = UIModalPresentationOverFullScreen;
            [weakSelf presentViewController:nav animated:YES completion:nil];
        };
    }else {
        self.yBGiftVC.userid = self.conversationData.userID;
        self.yBGiftVC.ySSendGiftType = YSSendGiftSingleType;
    }

    MJWeakSelf;
    self.yBGiftVC.peopleSendGiftBlock = ^(NSArray * _Nonnull sendWhoArr, YBGiftModel * _Nonnull model, BOOL isNeedTopUp) {
        if (isNeedTopUp) {
            YBTopUpVC *vc =[YBTopUpVC new];
            [weakSelf.navigationController pushViewController:vc animated:YES];
        }else{
            if (sendWhoArr.count > 0) {
                
                for (YBGiftUserModel *userModel in sendWhoArr) {
                    NSString *whoName = userModel.userName;
                    NSString *whoId = userModel.userId;
                    NSString *whoPic = userModel.userAvatar;
                    
                    NSDictionary *param = @{
                        @"businessID" : BussinessID_GiveGift,
                        @"img":model.picture?model.picture:@"",
                        @"type":@"@@@@@***",
                        @"giftsNum":model.count?model.count:@"",
                        @"giftsName":model.giftname?model.giftname:@"",
                        @"giftsId":model.identify?model.identify:@"",
                        @"giftsPrice":model.goldmoney?model.goldmoney:@"",
                        @"svgaUrl":model.svgaaddress?model.svgaaddress:@"",
                        @"sendGiftUserId":kUserInfo.tengxuncode?kUserInfo.tengxuncode:@"",
                        @"sendGiftUserName":kUserInfo.nick?kUserInfo.nick:@"",
                        @"songliUserPic":kUserInfo.pic?kUserInfo.pic:@"",
                        @"getGiftUserId":whoId?whoId:@"",
                        @"getGiftUserName":whoName?whoName:@"",
                        @"shouliUserPic":whoPic?whoPic:@"",
                    };
                    
                    NSData *data = [NSJSONSerialization dataWithJSONObject:param options:0 error:nil];
                    V2TIMMessage *message = [[V2TIMManager sharedInstance] createCustomMessage:data];
                    [weakSelf sendMessage:message];

                    //获取与对方的亲密度
                    [weakSelf requestAppGuardGetToUserIntimacy];
                    //SVGA动效
                    [[YBGiftTool shareInstance] playSvgaWithDic:param];
                    //飘屏动效
                    [[YBGiftTool shareInstance] moveScreenWithDic:param type:YBMoveScreenTypeSendGift];
                }
            }else {
                
                NSDictionary *param = @{
                    @"businessID" : BussinessID_GiveGift,
                    @"img":model.picture?model.picture:@"",
                    @"type":@"@@@@@***",
                    @"giftsNum":model.count?model.count:@"",
                    @"giftsName":model.giftname?model.giftname:@"",
                    @"giftsId":model.identify?model.identify:@"",
                    @"giftsPrice":model.goldmoney?model.goldmoney:@"",
                    @"svgaUrl":model.svgaaddress?model.svgaaddress:@"",
                    @"sendGiftUserId":kUserInfo.tengxuncode?kUserInfo.tengxuncode:@"",
                    @"sendGiftUserName":kUserInfo.nick?kUserInfo.nick:@"",
                    @"songliUserPic":kUserInfo.pic?kUserInfo.pic:@"",
                    @"getGiftUserId":weakSelf.friendInfoModel.tengxuncode?weakSelf.friendInfoModel.tengxuncode:@"",
                    @"getGiftUserName":weakSelf.friendInfoModel.nick?weakSelf.friendInfoModel.nick:@"",
                    @"shouliUserPic":weakSelf.friendInfoModel.pic?weakSelf.friendInfoModel.pic:@"",
                };

                NSData *data = [NSJSONSerialization dataWithJSONObject:param options:0 error:nil];
                V2TIMMessage *message = [[V2TIMManager sharedInstance] createCustomMessage:data];
                [weakSelf sendMessage:message];

                //获取与对方的亲密度
                [weakSelf requestAppGuardGetToUserIntimacy];
                //SVGA动效
                [[YBGiftTool shareInstance] playSvgaWithDic:param];
                //飘屏动效
                [[YBGiftTool shareInstance] moveScreenWithDic:param type:YBMoveScreenTypeSendGift];
            }
        }
        
    };
    self.yBGiftVC.modalPresentationStyle =UIModalPresentationOverCurrentContext;
    [self presentViewController:self.yBGiftVC animated:YES completion:nil];
}

//置顶
- (void)showTopView {
    [self.placetopView.headImgV sd_setImageWithURL:self.lastTextCellData.avatarUrl placeholderImage:kDefaultHead];
    self.placetopView.nameLab.text = self.lastTextCellData.name;
    self.placetopView.desLab.text = self.lastTextCellData.content;
    //时间格式
    NSDateFormatter * formatter = [[NSDateFormatter alloc]init];
    //YYYY-MM-dd HH:mm:ss
    [formatter setDateFormat:@"HH:mm"];
    //将时间转换为字符串
    NSString *timeStr = [formatter stringFromDate:self.lastTextCellData.innerMessage.timestamp];
    self.placetopView.timeLab.text = timeStr;
    self.placetopView.hidden = NO;
    
    self.messageController.tableView.tableHeaderView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, kScreenWidth, 70)];
}

#pragma mark - TUIJoinGroupMessageCellDelegate
- (void)didTapOnRestNameLabel:(TUIJoinGroupMessageCell *)cell withIndex:(NSInteger)index{
    NSString *userId = cell.joinData.userIDList[index];
    
    [self getUserOrFriendProfileVCWithUserID:userId succBlock:^(UIViewController *vc) {
        [self.navigationController pushViewController:vc animated:YES];
    } failBlock:^(int code, NSString *desc) {
        [TUITool makeToastError:code msg:desc];
    }];
}

#pragma mark - YBGiftCellDelegate
//点击礼物单元格上的回赠礼物/继续送礼按钮
- (void)onClickGiftBtn:(YBGiftCell *)cell {
    
    if (cell.customData.direction == MsgDirectionIncoming) {
        //消息接收，回赠礼物按钮点击
        YBGiftCellData *cellData = cell.customData;
        YBSendGiftAlertView *view = [[YBSendGiftAlertView alloc] initWithFrame:CGRectMake(0, 0, kScreenWidth, kScreenHeight) cellData:cellData intimacyZuanshi:[self.blackModel.intimacyZuanshi floatValue]];
        MJWeakSelf;
        view.yBSendGiftAlertViewBlock = ^(NSInteger giftCount) {
            [weakSelf requestAppsonglisonglinumWithCellData:cellData giftCount:giftCount];
        };
        [kWindow addSubview:view];
    }else if (cell.customData.direction == MsgDirectionOutgoing) {
        //消息发送，继续送礼按钮点击
        YBGiftCellData *cellData = cell.customData;
        YBSendGiftAlertView *view = [[YBSendGiftAlertView alloc] initWithFrame:CGRectMake(0, 0, kScreenWidth, kScreenHeight) cellData:cellData intimacyZuanshi:[self.blackModel.intimacyZuanshi floatValue]];
        MJWeakSelf;
        view.yBSendGiftAlertViewBlock = ^(NSInteger giftCount) {
            [weakSelf requestAppsonglisonglinumWithCellData:cellData giftCount:giftCount];
        };
        [kWindow addSubview:view];
    }
}

#pragma mark - V2TIMConversationListener
- (void)onConversationChanged:(NSArray<V2TIMConversation*> *) conversationList {
    for (V2TIMConversation *conv in conversationList) {
        if ([conv.conversationID isEqualToString:self.conversationData.conversationID]) {
            if (!self.conversationData.otherSideTyping) {
                self.conversationData.title = conv.showName;
            }
            break;
        }
    }
}

#pragma mark - V2TIMGroupListener
/// 收到 RESTAPI 下发的自定义系统消息
- (void)onReceiveRESTCustomData:(NSString *)groupID data:(NSData *)data {
    if (groupID && self.conversationData.groupID && [groupID isEqualToString:self.conversationData.groupID]) {
        NSDictionary *dic = data.mj_JSONObject;
        
        if ([dic[@"messageType"] intValue] == 265) {
            //飘屏动效
            [[YBGiftTool shareInstance] moveScreenWithDic:dic type:YBMoveScreenTypeEnterRoom];
            NSString *zuoqiStr = [NSString stringWithFormat:@"%@",dic[@"zuoqi"]];
            if(dic[@"zuoqi"] && zuoqiStr.length > 0) {
                NSDictionary *param = @{@"svgaUrl":zuoqiStr};
                //SVGA动效
                [[YBGiftTool shareInstance] playSvgaWithDic:param];
            }
        }
    }
}

#pragma mark - FriendInfoChangedNotification
- (void)onFriendInfoChanged:(NSNotification *)notice
{
    [self checkTitle:YES];
}
@end
